package com.nbcio.modules.erp.warehouse.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nbcio.common.core.domain.R;
import com.nbcio.modules.erp.warehouse.domain.ErpWarehouse;
import com.nbcio.modules.erp.warehouse.service.IErpWarehouseService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import jakarta.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;
import com.alibaba.excel.EasyExcel;
import com.nbcio.modules.erp.warehouse.excel.WarehouseExportDTO;

@Tag(name = "仓库管理")
@RestController
@RequestMapping("/erp/warehouse")
@RequiredArgsConstructor
public class ErpWarehouseController {

    private final IErpWarehouseService warehouseService;

    @GetMapping("/page")
    public R<IPage<ErpWarehouse>> page(@RequestParam int pageNum,
                                       @RequestParam int pageSize,
                                       @RequestParam(required = false) String warehouseCode,
                                       @RequestParam(required = false) String warehouseName,
                                       @RequestParam(required = false) Integer status,
                                       @RequestParam(required = false) Integer enableBin,
                                       @RequestParam(required = false) Integer enableBatch,
                                       @RequestParam(required = false) Integer enableSerial,
                                       @RequestParam(required = false) String startTime,
                                       @RequestParam(required = false) String endTime) {
        LambdaQueryWrapper<ErpWarehouse> qw = new LambdaQueryWrapper<>();
        if (warehouseCode != null && !warehouseCode.isEmpty()) {
            qw.like(ErpWarehouse::getWarehouseCode, warehouseCode);
        }
        if (warehouseName != null && !warehouseName.isEmpty()) {
            qw.like(ErpWarehouse::getWarehouseName, warehouseName);
        }
        if (status != null) { qw.eq(ErpWarehouse::getStatus, status); }
        if (enableBin != null) { qw.eq(ErpWarehouse::getEnableBin, enableBin); }
        if (enableBatch != null) { qw.eq(ErpWarehouse::getEnableBatch, enableBatch); }
        if (enableSerial != null) { qw.eq(ErpWarehouse::getEnableSerial, enableSerial); }
        if (startTime != null && endTime != null && !startTime.isEmpty() && !endTime.isEmpty()) { qw.between(ErpWarehouse::getCreateTime, startTime, endTime); }
        IPage<ErpWarehouse> page = warehouseService.page(Page.of(pageNum, pageSize), qw);
        return R.ok(page);
    }

    @GetMapping("/{id}")
    public R<ErpWarehouse> get(@PathVariable("id") String id) {
        ErpWarehouse data = warehouseService.getById(Long.parseLong(id));
        return R.ok(data);
    }

    @PostMapping
    public R<Boolean> create(@RequestBody ErpWarehouse dto) {
        return R.ok(warehouseService.save(dto));
    }

    @PutMapping("/{id}")
    public R<Boolean> update(@PathVariable("id") String id, @RequestBody ErpWarehouse dto) {
        dto.setWarehouseId(Long.parseLong(id));
        return R.ok(warehouseService.updateById(dto));
    }

    @DeleteMapping("/{id}")
    public R<Boolean> remove(@PathVariable("id") String id) {
        return R.ok(warehouseService.removeById(Long.parseLong(id)));
    }

    @PostMapping("/batch-delete")
    public R<Boolean> batchDelete(@RequestBody List<String> ids) {
        List<Long> longIds = ids.stream().map(Long::parseLong).collect(Collectors.toList());
        return R.ok(warehouseService.removeByIds(longIds));
    }

    @GetMapping("/export")
    public void export(HttpServletResponse response,
                       @RequestParam(required = false) String warehouseCode,
                       @RequestParam(required = false) String warehouseName,
                       @RequestParam(required = false) Integer status,
                       @RequestParam(required = false) Integer enableBin,
                       @RequestParam(required = false) Integer enableBatch,
                       @RequestParam(required = false) Integer enableSerial,
                       @RequestParam(required = false) String startTime,
                       @RequestParam(required = false) String endTime,
                       @RequestParam(required = false) List<String> ids,
                       @RequestParam(required = false) List<String> columns) throws Exception {
        LambdaQueryWrapper<ErpWarehouse> qw = new LambdaQueryWrapper<>();
        if (warehouseCode != null && !warehouseCode.isEmpty()) { qw.like(ErpWarehouse::getWarehouseCode, warehouseCode); }
        if (warehouseName != null && !warehouseName.isEmpty()) { qw.like(ErpWarehouse::getWarehouseName, warehouseName); }
        if (status != null) { qw.eq(ErpWarehouse::getStatus, status); }
        if (enableBin != null) { qw.eq(ErpWarehouse::getEnableBin, enableBin); }
        if (enableBatch != null) { qw.eq(ErpWarehouse::getEnableBatch, enableBatch); }
        if (enableSerial != null) { qw.eq(ErpWarehouse::getEnableSerial, enableSerial); }
        if (startTime != null && endTime != null && !startTime.isEmpty() && !endTime.isEmpty()) { qw.between(ErpWarehouse::getCreateTime, startTime, endTime); }
        if (ids != null && !ids.isEmpty()) { qw.in(ErpWarehouse::getWarehouseId, ids.stream().map(Long::parseLong).toList()); }
        List<ErpWarehouse> list = warehouseService.list(qw);
        List<WarehouseExportDTO> rows = list.stream().map(it -> {
            WarehouseExportDTO dto = new WarehouseExportDTO();
            dto.setWarehouseCode(it.getWarehouseCode());
            dto.setWarehouseName(it.getWarehouseName());
            dto.setOrgId(it.getOrgId() == null ? null : String.valueOf(it.getOrgId()));
            dto.setEnableBinText(it.getEnableBin() != null && it.getEnableBin() == 1 ? "是" : "否");
            dto.setEnableBatchText(it.getEnableBatch() != null && it.getEnableBatch() == 1 ? "是" : "否");
            dto.setEnableSerialText(it.getEnableSerial() != null && it.getEnableSerial() == 1 ? "是" : "否");
            dto.setStatusText(it.getStatus() != null && it.getStatus() == 1 ? "启用" : "停用");
            dto.setRemark(it.getRemark());
            dto.setCreateTime(it.getCreateTime());
            return dto;
        }).toList();
        String fileName = URLEncoder.encode("仓库列表.xlsx", StandardCharsets.UTF_8.name()).replaceAll("\\+", "%20");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);
        var writer = EasyExcel.write(response.getOutputStream(), WarehouseExportDTO.class);
        if (columns != null && !columns.isEmpty()) {
            writer.includeColumnFieldNames(new java.util.HashSet<>(columns));
        }
        writer.sheet("仓库").doWrite(rows);
    }

    @GetMapping("/ids")
    public R<List<String>> ids(@RequestParam(required = false) String warehouseCode,
                               @RequestParam(required = false) String warehouseName,
                               @RequestParam(required = false) Integer status,
                               @RequestParam(required = false) Integer enableBin,
                               @RequestParam(required = false) Integer enableBatch,
                               @RequestParam(required = false) Integer enableSerial,
                               @RequestParam(required = false) String startTime,
                               @RequestParam(required = false) String endTime) {
        LambdaQueryWrapper<ErpWarehouse> qw = new LambdaQueryWrapper<>();
        if (warehouseCode != null && !warehouseCode.isEmpty()) { qw.like(ErpWarehouse::getWarehouseCode, warehouseCode); }
        if (warehouseName != null && !warehouseName.isEmpty()) { qw.like(ErpWarehouse::getWarehouseName, warehouseName); }
        if (status != null) { qw.eq(ErpWarehouse::getStatus, status); }
        if (enableBin != null) { qw.eq(ErpWarehouse::getEnableBin, enableBin); }
        if (enableBatch != null) { qw.eq(ErpWarehouse::getEnableBatch, enableBatch); }
        if (enableSerial != null) { qw.eq(ErpWarehouse::getEnableSerial, enableSerial); }
        if (startTime != null && endTime != null && !startTime.isEmpty() && !endTime.isEmpty()) { qw.between(ErpWarehouse::getCreateTime, startTime, endTime); }
        List<String> idList = warehouseService.list(qw).stream().map(it -> String.valueOf(it.getWarehouseId())).collect(Collectors.toList());
        return R.ok(idList);
    }
}


